package com.hrm.action;

import com.hrm.action.annotation.Action;
import com.hrm.action.annotation.RequestPath;
import org.reflections.Reflections;
import sun.reflect.Reflection;

import javax.servlet.ServletContextEvent;
import javax.servlet.ServletContextListener;
import java.lang.annotation.Annotation;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.lang.reflect.Parameter;
import java.util.*;

/**
 * Create by zekdot on 20-2-25.
 */
public class InitListener implements ServletContextListener {
    @Override
    public void contextInitialized(ServletContextEvent servletContextEvent) {
        InitListener initListener = new InitListener();
        try {
            initListener.resolveAction();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
    }

    @Override
    public void contextDestroyed(ServletContextEvent servletContextEvent) {

    }

    /**
     * 解析所有action
     */
    public void resolveAction() throws IllegalAccessException, InstantiationException {
        // 反射获取整个包
        Reflections reflections = new Reflections("com.hrm.action.*");
        // 获取包中所有类
        Set<Class<?>> classes = reflections.getTypesAnnotatedWith(Action.class);
        // 遍历每一个类
        for(Class<?> cl:classes){
            // 获取类上的注解
            RequestPath requestPath = cl.getAnnotation(RequestPath.class);
            // 获取注解的顶层路径
            String firstPath = requestPath.path();
            // 类层级的list列表
            List<Object> objects = new ArrayList<>();
            // 将list放在列表中
            BaseAction.urls.put(firstPath,objects);
            // list的第一个元素放类实例
            objects.add(cl.newInstance());
            // 新建一个方法字典
            Map<String,Object> methodMap = new HashMap<>();
            // list的第二个元素放方法字典
            objects.add(methodMap);
            // 获取该类中所有方法
            Method[] methods = cl.getMethods();
            // 遍历所有方法
            for(Method method:methods){
                // 获取方法上的注解
                requestPath = method.getDeclaredAnnotation(RequestPath.class);
                // 跳过没有注解的方法
                if(requestPath == null)
                    continue;
                // 获取二级路径
                String secondPath = requestPath.path();
                // 新建方法层级的list
                objects = new ArrayList<>();
                // 把object放在字典中
                methodMap.put(secondPath,objects);
                // list第一个元素放方法本身
                objects.add(method);
                // 解析方法参数列表 names
                Parameter parameters[] = method.getParameters();
                for(Parameter parameter:parameters){
                    // 后面的添加参数列表
                    objects.add(parameter);
                }
            }
        }
    }
    public static void main(String args[]){
        try {
            // 解析
            new InitListener().resolveAction();
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InstantiationException e) {
            e.printStackTrace();
        }
        List l = (List) BaseAction.urls.get("/employer");
        Object o = l.get(0);
        Map<String,Object> map = (Map<String, Object>) l.get(1);
        List list = (List) map.get("/info");
        Method m = (Method) list.get(0);
        try {
            System.out.println(m.invoke(o,"test"));
        } catch (IllegalAccessException e) {
            e.printStackTrace();
        } catch (InvocationTargetException e) {
            e.printStackTrace();
        }
        ;
    }
}
